home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / c / pcw.zip / PCINT24A.ASM < prev    next >
Assembly Source File  |  1991-12-16  |  11KB  |  210 lines

  1.               Page      ,132
  2. ;****************************************************************
  3. ;* File Id.                       Int24a.Asm                    *
  4. ;* Author.                        Stan Milam.                   *
  5. ;* Date Written.                  11/05/89.                     *
  6. ;*                                                              *
  7. ;*          (c) Copyright 1989, 1990 by Stan Milam              *
  8. ;*                                                              *
  9. ;* Comments:  This code will act as an interrupt handler for    *
  10. ;* interrupt 24, the DOS Critical Interrupt.  It will preserve  *
  11. ;* the stack, restore the applications DS & ES register and pass*
  12. ;* information about the critical error to a C function that    *
  13. ;* will use a pop-up menu window to give information and accept *
  14. ;* input to the user.                                           *
  15. ;*                                                              *
  16. ;* Added code to switch stacks to allow interrupt to be called  *
  17. ;* by a child process.  Stack at time of DOS interrupt is stored*
  18. ;* at offset 0x2e of Program Segment Prefix.                    *
  19. ;* Added code to FAIL the operation when return code is 3 even  *
  20. ;* in DOS versions before 3.1.                                  *
  21. ;*                                                              *
  22. ;* If C function returns -1 (0xffff) we must call the original  *
  23. ;* Int 24.                                                      *
  24. ;*                                                              *
  25. ;* Research material:                                           *
  26. ;*      PC Tech Journal, April 1987, Exception Handling         *
  27. ;*      Advanced MS-DOS, Second Edition, by Ray Duncan          *
  28. ;*      MS-DOS Encyclopedia                                     *
  29. ;****************************************************************
  30. ;
  31.               Dosseg                        ;Declare Normal Segmentation
  32. IFDEF POWERC
  33.               .Model    Large               ;Large Model for Power C
  34. ELSE
  35.               .Model    Large,C             ;And Turbo & MSC
  36. ENDIF
  37.               Extrn     old_int24:Dword     ;Address of old interrupt
  38.               Extrn     _psp:Word           ;Segment Address of PSP
  39.               .Code
  40.               Extrn     Critical_Interrupt:Far
  41. ;
  42. ; Declare storage in the code segment to save ES & DS
  43. ;
  44. old_es        Dw        0
  45. old_ds        Dw        0
  46. save_ss       Dw        ?
  47. save_sp       Dw        ?
  48.               Page
  49. ;
  50. ;****************************************************************
  51. ;*                             Int24                            *
  52. ;*                                                              *
  53. ;* This routine will be entered when interrupt 24 is generated  *
  54. ;* by DOS.                                                      *
  55. ;*                                                              *
  56. ;* Major Goals: Save stack, Restore application DS & ES, push   *
  57. ;* information on stack & call C routine, return to DOS with    *
  58. ;* return information in AX                                     *
  59. ;* If -1 (0xffff) is returned by C routine then restore regs &  *
  60. ;* invoke the original INT 24 handler.                          *
  61. ;****************************************************************
  62. ;
  63.               Public    Int24
  64. Int24         Proc      Far
  65.               Push      Bp                  ;Set up the stack frame
  66.               Mov       Bp,Sp
  67.               Push      Ds                  ;Preserve the registers
  68.               Push      Es
  69.               Push      Bx
  70.               Push      Cx
  71.               Mov       Cx,[Bp]             ;Save Bp because we swithc stacks
  72. IFDEF POWERC
  73.               Push      Cs:[old_ds]         ;Restore Data Segment
  74.               Pop       Ds
  75.               Mov       Bx,_psp             ;Get PSP Address in Es so
  76.               Mov       Es,Bx               ;We can switch stacks.
  77. ELSE
  78.               Mov       Bx,@Data            ;This the way we restore DS &
  79.               Mov       Ds,Bx               ;get the PSP address in Turbo C
  80.               Mov       Bx,Seg _psp         ;and Microsoft C.
  81.               Mov       Es,Bx               ;This method accomodates all of
  82.               Mov       Bx,Es:[_psp]        ;the different memory models.
  83.               Mov       Es,Bx
  84. ENDIF
  85.               Mov       Cs:[save_ss],Ss     ;Save Stack address in Code Seg
  86.               Mov       Cs:[save_sp],Sp     ;So we can switch
  87.               Mov       Ss,Es:[30h]         ;Switch stacks, this allows
  88.               Mov       Sp,Es:[2eh]         ;Child process to use interrupt
  89.               Sub       Sp,0eh              ;Protect Stack if not child
  90.               Sti                           ;Start Interrupts
  91.               Push      Dx                  ;Now save every thing else
  92.               Push      Si
  93.               Push      Di
  94. ;
  95. ;These next 4 pushes are parms to C function
  96. ;
  97.               Push      Cx                  ;Bp:Si is far pointer to
  98.               Push      Si                  ;Device Header
  99.               Push      Di                  ;Di & Ax are parms to C
  100.               Push      Ax                  ;routine.  Info passed by DOS.
  101.               Call      Critical_Interrupt  ;Call C routine
  102.               Cli                           ;Turn off interrupts
  103.               Cmp       Ax,0FFFFh           ;Was -1 returned?
  104.               Jne       Norm_Exit           ;No, so return with value in Ax
  105.               Page
  106. ;
  107. ;**************************************************************
  108. ;* This part of the code is going to call the orininal INT 24 *
  109. ;* To do this we must maintain Ds & Es becuase the pointer to *
  110. ;* the old INT 24 is stored in the Data Segment of our        *
  111. ;* program.  However, we restore all other registers. Notice  *
  112. ;* the strange manipulations of the stack that had to be made *
  113. ;* to preserve Ds & Es.                                       *
  114. ;**************************************************************
  115. ;
  116. IFDEF POWERC
  117.               Push      Ds                  ;Force Es & DS to be same
  118.               Pop       Es                  ;To point at old interrupt
  119. ELSE
  120.               Mov       Ax,Seg old_int24    ;Get Segment address for 
  121.               Mov       Es,Ax               ;Old interrupt
  122. ENDIF
  123.               Pop       Ax                  ;Else restore registers as they
  124.               Add       Sp,+6               ;were upon entry and call the
  125.               Pop       Di                  ;original INT 24 handler (Except
  126.               Pop       Si                  ;for Es & Ds)
  127.               Pop       Dx
  128.               Mov       Ss,Cs:[save_ss]     ;Switch stacks back
  129.               Mov       Sp,Cs:[save_sp]
  130.               Pop       Cx                  ;
  131.               Pop       Bx
  132.               Mov       Sp,Bp
  133.               Pop       Bp                  ;Restored everything but Ds & Es
  134.               Sub       Sp,+6               ;Save Bp,Es,Ds
  135.               Pushf                         ;Push flags to fake an interrupt
  136.               Call      Es:Dword Ptr old_int24 ;Call to old INT 24
  137.               Pop       Es                  ;Finally, Restore Ds & Es!
  138.               Pop       Ds
  139.               Pop       Bp
  140.               Jmp       Exit
  141. Norm_Exit:
  142.               Mov       Bx,Ax               ;Restore Ah to the way it was
  143.               Pop       Ax                  ;When we entered leaving return
  144.               Mov       Al,Bl               ;Code in Al.
  145.               Add       Sp,+6               ;Remove Parms to C code
  146.               Pop       Di                  ;Restore Registers but return
  147.               Pop       Si                  ;User action in Ax
  148.               Pop       Dx                    
  149.               Mov       Ss,Cs:[save_ss]     ;Switch stacks back
  150.               Mov       Sp,Cs:[save_sp]
  151.               Pop       Cx                  ;Be sure to restore these
  152.               Pop       Bx
  153.               Pop       Es
  154.               Pop       Ds
  155.               Mov       Sp,Bp
  156.               Pop       Bp
  157. Exit:
  158.               Cmp       Al,3                ;Was it a FAIL request?
  159.               Je        Fail                ;Yes it was
  160.               Iret                          ;Not a FAIL--Return to Dos
  161.               Page
  162. ;
  163. ;**************************************************************
  164. ;*                             FAIL                           *
  165. ;*                                                            *
  166. ;* Since the FAIL option does not exist in versions of DOS    *
  167. ;* before 3.1 I have written my own fail operation.  Simply   *
  168. ;* restores registers, move 0xffff into Ax (?), set the carry *
  169. ;* flag, and RET 2 back to the interrupted program.           *
  170. ;**************************************************************
  171. ;
  172. Fail:         Add       Sp,6                ;Remove DOS return address
  173.               Pop       Bx                  ;Restore program registers
  174.               Pop       Bx
  175.               Pop       Cx
  176.               Pop       Dx
  177.               Pop       Si
  178.               Pop       Di
  179.               Pop       Bp
  180.               Pop       Ds
  181.               Pop       Es
  182.               Mov       Ax,0ffffh           ;Error return code
  183.               Stc                           ;Set Carry flag
  184.               Sti                           ;Start interrupts again
  185.               Ret       2                   ;Return to DOS remove Flags
  186. Int24         Endp
  187.  
  188. IFDEF POWERC
  189.               Page
  190. ;
  191. ;********************************************************************
  192. ;*                           _Save_ES_DS_                           *
  193. ;*                                                                  *
  194. ;* Here we save Es & Ds values in the Code Segment so we can re-    *
  195. ;* trieve and restore them when the interrupt occurs.  If we do not *
  196. ;* reset these registers our C code will not work.  This routine is *
  197. ;* called by the installation routine set_int24().                  *
  198. ;********************************************************************
  199. ;
  200.               Public    _Save_ES_DS_
  201. _Save_ES_DS_  Proc      Far
  202.               Push      Es                  ;Save Es on Stack
  203.               Pop       Cs:[old_es]         ;Pop it into our Code Segment
  204.               Push      Ds                  ;Same thing with Ds
  205.               Pop       Cs:[old_ds]
  206.               Ret
  207. _Save_ES_DS_  Endp
  208. ENDIF
  209.               End
  210.